home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / simula / books / books.lha / kirkerud / stud1.sim < prev    next >
Text File  |  1993-08-16  |  18KB  |  466 lines

  1. % ****************************************************************
  2. % *                                                              *
  3. % *  This is tre program constructed in chapter 8 of             *
  4. % *  Object Oriented Programming with Simula by Bj|rn Kirkerud;  *
  5. % *                                                              *
  6. % ****************************************************************
  7.  
  8.  
  9. begin
  10.  
  11. % ****************************************************************
  12. % *                                                              *
  13. % *    First a declaration of the pattern for Student-objects:   *
  14. % *                                                              *
  15. % ****************************************************************
  16.  
  17.   class Student;
  18.     begin
  19.  
  20.       integer     ident, year, month, day, form;
  21.       Boolean     female;
  22.       character   math_grade, eng_grade, hist_grade;
  23.  
  24.       procedure read;
  25.         begin
  26.           ident         := prompt_for_int("Identity number? ");
  27.           year          := prompt_for_int("Year of birth? ");
  28.           month      := prompt_for_int("Month? ");
  29.           day          := prompt_for_int("Day? ");
  30.           form          := prompt_for_int("Form? ");
  31.           female     := prompt_for_bool("Female? ");
  32.           math_grade := prompt_for_char("Grade in mathematics? ");
  33.           eng_grade  := prompt_for_char("Grade in English? ");
  34.           hist_grade := prompt_for_char("Grade in history? ");
  35.         end of Student'read;
  36.  
  37.       procedure write;
  38.         begin
  39.           outtext("Data for student: "); outint(ident, 6);
  40.           outtext(".  Born: ");    outint(day,     2);   outchar('/');
  41.              outint(month,   2);   outchar('/');
  42.              outint(year,    4);
  43.           outtext(if female then ".  Female."  else ".  Male."); outimage;
  44.           outtext("  Form: "); outint(form, 1);
  45.           outtext(".  Current grades:");
  46.             outtext("  Mathematics: ");  outchar(math_grade);
  47.             outtext("  English: ");      outchar(eng_grade);
  48.             outtext("  History: ");      outchar(hist_grade); outimage;
  49.         end of Student'write;
  50.  
  51.       procedure change;
  52.         begin character attribute;
  53.           attribute := prompt_for_char("What do you want  to change? ");
  54.           if attribute = 'i' then ident :=
  55.                prompt_for_int("New identity number? ")   else
  56.           if attribute = 'y' then year :=
  57.                prompt_for_int("New birth year? ")     else
  58.           if attribute = 'm' then month :=
  59.                prompt_for_int("New birth month? ")       else
  60.           if attribute = 'd' then day :=
  61.                prompt_for_int("New day of birth? ")      else
  62.           if attribute = 'f' then form :=
  63.                prompt_for_int("New form number? ")       else
  64.           if attribute = 's' then female :=
  65.                prompt_for_bool("Female? ")               else
  66.           if attribute = 'a' then math_grade :=
  67.                prompt_for_char("New grade in math? ")    else
  68.           if attribute = 'e' then eng_grade :=
  69.                prompt_for_char("New grade in English? ") else
  70.           if attribute = 'h' then hist_grade :=
  71.                prompt_for_char("New grade in  history? ")
  72.           else begin
  73.               User_message("You can change the following  attributes:");
  74.               User_message("  i: Identity number");
  75.               User_message("  y: Birth year");
  76.               User_message("  m: Birth month");
  77.               User_message("  d: Day of birth");
  78.               User_message("  f: Form number");
  79.               User_message("  s: Sex");
  80.               User_message("  a: Grade in mathematics");
  81.               User_message("  e: Grade in English");
  82.               User_message("  h: Grade in history");
  83.               change; !  Observe that this is an invocation of  the procedure
  84.                       !  that is under declaration.  The effect of this is
  85.                       !  that this procedure is  executed once more, and hence
  86.                       !  that the user is given another  chance to change;
  87.             end;
  88.         end of Student'change;
  89.  
  90.       character procedure worst_grade;
  91.         worst_grade := max(math_grade, max(eng_grade,  hist_grade));
  92.  
  93.       Boolean procedure is_elder_than(a_student);  ref(Student) a_student;
  94.         is_elder_than :=
  95.             (year < a_student.year) or else
  96.             (year = a_student.year and month < a_student.month) or else
  97.             (year = a_student.year and month = a_student.month
  98.                            and day < a_student.day);
  99.  
  100.       procedure put_in_record;
  101.         not_implemented("Put in record");
  102.  
  103.       procedure get_from_record;
  104.         not_implemented("Get from record");
  105.  
  106.     end of Student;
  107.  
  108.  
  109. % ******************************************************************
  110. % *                                                                *
  111. % *  A class containing declarations of the variables of the data  *
  112. % *  structure and procedures for accessing the data structure:    *
  113. % *                                                                *
  114. % ******************************************************************
  115.  
  116.   class School(max_number_of_students);  integer max_number_of_students;
  117.       protected The_students, number_of_students,
  118.                   last_index, find_index_of_student;
  119.       !  The effect of this is to protect these  four attributes,
  120.       !  thus making them inaccessible outside the  the class.
  121.       !  This means that all access of the  data structure must
  122.       !  be via the five data access  procedures declared in the class;
  123.     begin
  124.  
  125.  
  126.     ! Declaration of data structure which consists of:
  127.     !  1:  An array which may store references to as  many as
  128.     !      max_number_of_students Students
  129.     !  2:  An integer which says how many Students  are  stored in the array: ;
  130.  
  131.       ref(Student) array The_students(1 :  max_number_of_students);
  132.       integer number_of_students;
  133.  
  134.     !   Data invariants:  ;
  135.     !   1:  0 le number_of_students le  max_number_of_students;
  136.     !   2: For every stud_n =  1, 2, ... number_of_students:
  137.     !         The_students(stud_n)   points to a Student   object, not none;
  138.     !   3: For every stud_n  = number_of_students + 1, ...,
  139.     !       max_number_of_students: The_students(stud_n) == none;
  140.     !   4: For every s1, s2  = 1, 2, ... number_of_students (s1 ne s2):
  141.     !       The_students(s1) =/=  The_students(s2);
  142.     !       The_students(s1)ident ne  The_students(s2)ident;
  143.  
  144.  
  145.     !  Declaration of an auxiliary integer variable to hold
  146.     !  the index last used by the procedure next_student:   ;
  147.  
  148.       integer last_index;
  149.  
  150.  
  151.     !   Declarations of data access procedures:   ;
  152.  
  153.       procedure Place_student(a_student, no_room, ident_exists);
  154.           name no_room, ident_exists;
  155.           ref(Student) a_student;  Boolean no_room, ident_exists;
  156.       if number_of_students = max_number_of_students
  157.         then no_room := true
  158.         else begin
  159.           no_room := false;
  160.           if find_student(a_student.ident) =/= none  then ident_exists := true
  161.           else begin
  162.               ident_exists := false;
  163.               number_of_students := number_of_students + 1;
  164.               The_students(number_of_students) :- a_student;
  165.             end;
  166.           end Place_student;
  167.  
  168.       ref(Student) procedure first_student;
  169.         begin
  170.           first_student :- The_students(1);
  171.           last_index    := 1;
  172.         end of first_student;
  173.  
  174.       ref(Student) procedure next_student;
  175.         begin
  176.           last_index   := last_index + 1;
  177.           next_student :- if last_index > number_of_students
  178.                       then none
  179.                       else The_students(last_index);
  180.         end of next_student;      
  181.  
  182.       procedure Remove_specified_student(ident, no_such_student);
  183.           name no_such_student;
  184.           integer ident; Boolean no_such_student;
  185.         begin integer ident_index; Boolean ident_exists;
  186.           find_index_of_student(ident, ident_exists, ident_index);
  187.           if ident_exists then
  188.             begin
  189.               no_such_student := false;
  190.               The_students(ident_index) :- The_students(number_of_students);
  191.               The_students(number_of_students) :- none;
  192.               number_of_students := number_of_students - 1;
  193.             end
  194.           else no_such_student := true;
  195.         end of Remove_specified_student;
  196.  
  197.       ref(Student) procedure find_student(ident_number);  integer ident_number;
  198.         begin integer student_number;  Boolean student_found;
  199.           find_index_of_student(ident_number,  student_found, student_number);
  200.           find_student :- if student_found  then The_students(student_number)
  201.                 else   none
  202.         end of find_student;
  203.  
  204.     !   Declaration of an auxiliary, protected data access procedure:   ;
  205.  
  206.       procedure find_index_of_student(ident, ident_found,  ident_index);
  207.           name ident_found, ident_index;
  208.           integer ident, ident_index; Boolean ident_found;
  209.         begin
  210.           ident_index := 1; ident_found := false;
  211.           while ident_index le number_of_students and  not ident_found do
  212.             if The_students(ident_index).ident = ident
  213.               then ident_found := true  else ident_index := ident_index + 1;
  214.         end of find_index_of_student;
  215.  
  216.     end of School;
  217.  
  218.  
  219. % ******************************************
  220. % *                                        *
  221. % *  Declarations of command procedures:   *
  222. % *                                        *
  223. % ******************************************
  224.  
  225. procedure Enter_student;
  226.   begin  ref(Student) a_student; Boolean no_room, ident_exists;
  227.     a_student :- new Student;
  228.     a_student.read;
  229.     The_school.Place_student(a_student, no_room, ident_exists);
  230.     if no_room
  231.       then User_message("Sorry, no more room!") else
  232.     if ident_exists
  233.       then User_message("The identity number is already  in use!")
  234.       else User_message("The data have been stored.");
  235.   end of Enter_student;
  236.  
  237.  
  238. procedure Write_student;
  239.   begin integer ident_number; ref(Student) a_student;
  240.     ident_number :=  prompt_for_int("Identity number? ");
  241.     a_student    :-  The_school.find_student(ident_number);
  242.     if a_student == none
  243.       then User_message("No student with that  identity number!")
  244.       else a_student.write;
  245.   end of Write_student;
  246.  
  247.  
  248. procedure List_students;
  249.   begin ref(Student) a_student;
  250.     User_message("The students for which data have  been entered:");
  251.     a_student :- The_school.first_student;
  252.     while a_student =/= none do
  253.       begin a_student.write;  a_student :- The_school.next_student end;
  254.   end of List_students;
  255.  
  256.  
  257. procedure Change_student;
  258.   begin ref(Student) a_student; integer ident_number;
  259.     ident_number := prompt_for_int("Identity number? ");
  260.     a_student :- The_school.find_student(ident_number);
  261.     if a_student == none
  262.       then User_message("No student with that  identity number!")
  263.       else begin a_student.write;  a_student.change end;
  264.   end of Change_student;
  265.  
  266.  
  267. procedure Remove_student;
  268.   begin integer ident_number;  Boolean no_such_student;
  269.     ident_number := prompt_for_int("Identity number? ");
  270.     The_school.Remove_specified_student(ident_number, no_such_student);
  271.     if no_such_student
  272.       then User_message("No student with that identity  number!")
  273.       else User_message("The student has been removed!");
  274.   end of Remove_student;
  275.  
  276.  
  277. procedure Put_to_file;
  278.   not_implemented("Put to file");
  279.  
  280. procedure Get_from_file;
  281.   not_implemented("Get from file");
  282.  
  283. % The  procedures which put data to file and get data from file 
  284. % will be implemented when more powerful file tools have been  
  285. % introduced in chapter 12;
  286.  
  287.  
  288. procedure Bad_grades;
  289.   begin character grade_limit;  ref(Student) a_student;
  290.     grade_limit := prompt_for_char("Grade limit? ");
  291.     a_student :- The_school.first_student;
  292.     while a_student =/= none do
  293.       begin
  294.         if a_student.worst_grade ge grade_limit then a_student.write;
  295.         a_student :- The_school.next_student;
  296.       end;
  297.   end of Bad_grades;
  298.  
  299.  
  300. procedure Sort_form;
  301.   begin
  302.     integer form, number_in_form, student_number;
  303.     ref(Student) array The_form(1 : 300);
  304.     ref(Student) a_student;
  305.     form := prompt_for_int("Form number? ");
  306.   ! Make a list of all students in the specified  form:    ;
  307.     a_student :- The_school.first_student;
  308.     while a_student =/= none do
  309.       begin
  310.         if a_student.form = form  and then number_in_form < 300 then
  311.           begin
  312.             number_in_form := number_in_form + 1;
  313.             The_form(number_in_form) :- a_student;
  314.           end;
  315.         a_student :- The_school.next_student;
  316.       end;
  317.   ! Sort the list on age:    ;
  318.     Sort_on_age(The_form, number_in_form);
  319.       !  The auxiliary procedure Sort_on_age is declarec below;
  320.   ! Write the list:    ;
  321.     for student_number := 1 step 1 until  number_in_form do
  322.       The_form(student_number).write;
  323.   end of Sort_form;
  324.  
  325.  
  326. procedure Give_help;
  327.   begin
  328.     User_message("The legal commands are: ");
  329.     User_message("   ?:  Help (writes this text)");
  330.     User_message("   E:  To enter data about a new student");
  331.     User_message("   W:  Writes data about a specified  student");
  332.     User_message("   L:  Writes a list with all students");
  333.     User_message("   C:  Changes data about a specified  student");
  334.     User_message("   R:  Removes data about a specified  student");
  335.     User_message("   P:  Puts all data to file ""Stud.dta""");
  336.     User_message("   G:  Gets data from file ""stud.dta""");
  337.     User_message("   B:  Writes students with bad grades");
  338.     User_message("   S:  Writes students in a specified  form sorted on age");
  339.     User_message("   Q:  Quit (the program execution stops)");
  340.   end of Give_help;
  341.  
  342.  
  343. % ******************************************
  344. % *                                        *
  345. % *  Declarations of auxiliary procedures: *
  346. % *                                        *
  347. % ******************************************
  348.  
  349.   procedure Unknown_command(c); character c;
  350.     begin
  351.       outtext("   You gave the command '"); outchar(c);
  352.       outtext("'.  This is not among the legal commands.");  outimage;
  353.       outtext("   Type ? if you don't remember the commands");  outimage;
  354.     end of Unknown command;
  355.  
  356.   character procedure prompt_for_char(prompt);  text prompt;
  357.     begin
  358.       outtext(prompt); breakoutimage; inimage;
  359.       prompt_for_char := inchar;
  360.     end of prompt_for_char;
  361.  
  362.   integer procedure prompt_for_int(prompt);  text prompt;
  363.     begin
  364.       outtext(prompt); breakoutimage; inimage;
  365.       prompt_for_int := inint;
  366.     end of prompt_for_int;
  367.  
  368.   Boolean procedure prompt_for_bool(prompt);  text prompt;
  369.     begin character c;
  370.       outtext(prompt); breakoutimage; inimage;
  371.       c := inchar;
  372.       prompt_for_bool := c = 'y' or c = 'Y';
  373.     end of prompt_for_char;
  374.  
  375.   procedure not_implemented(action_name);  text action_name;
  376.     begin
  377.       outtext("   You gave the command """);  outtext(action_name);
  378.       outtext(""".  This has not been implemented yet!");  outimage;
  379.       outtext("   Try another command!"); outimage;
  380.     end;
  381.  
  382.   procedure User_message(message); text message;
  383.     begin outtext(message); outimage end;
  384.  
  385.   procedure Sort_on_age(Student_list, list_length);
  386.       ref(Student) array Student_list;  integer list_length;
  387.   begin integer ind, k, index_of_oldest;  ref(Student) swap_aux;
  388.     for ind := 1 step 1 until list_length - 1  do
  389.       begin
  390.         index_of_oldest := ind;
  391.         for k := ind + 1 step 1 until list_length  do
  392.           if Student_list(k).is_elder_than(Student_list(index_of_oldest))
  393.             then index_of_oldest := k;
  394.         if ind ne index_of_oldest then
  395.           begin
  396.             swap_aux :- Student_list(index_of_oldest);
  397.             Student_list(index_of_oldest) :- Student_list(ind);
  398.             Student_list(ind) :- swap_aux;
  399.           end;
  400.       end;
  401.   end Sort_on_age;
  402.  
  403.  
  404. % ********************************************************
  405. % *                                                      *
  406. % *  Declaration of a variable to hold the last command  *
  407. % *  typed by the user:                                  *
  408. % *                                                      *
  409. % ********************************************************
  410.  
  411.   character command;
  412.  
  413.  
  414. % **********************************************************
  415. % *                                                        *
  416. % *  Declaration of a variable to hold the data structure  *
  417. % *       (which is insied a single School-object):        *
  418. % *                                                        *
  419. % **********************************************************
  420.  
  421.   ref(School) The_school;
  422.  
  423.  
  424.  
  425. % **********************************************************
  426. % *                                                        *
  427. % *           That was the last declaration.               *
  428. % *      Now come the imperatives of this program:         *
  429. % *                                                        *
  430. % **********************************************************
  431.  
  432. % **********************************************************
  433. % *                                                        *
  434. % *  Initialization of data structure for 1500  students:  *
  435. % *                                                        *
  436. % **********************************************************
  437.  
  438.     The_school :- new School(1500);
  439.  
  440.  
  441. % ****************************************************
  442. % *                                                  *
  443. % *  Read and interpret commands typed by the user:  *
  444. % *                                                  *
  445. % ****************************************************
  446.  
  447.   command := prompt_for_char("Type your first command  (? for help) > ");
  448.   while command ne 'Q' do
  449.     begin
  450.       if command = '?' then Give_help        else
  451.       if command = 'E' then Enter_student  else
  452.       if command = 'W' then Write_student  else
  453.       if command = 'L' then List_students  else
  454.       if command = 'C' then Change_student else
  455.       if command = 'R' then Remove_student else
  456.       if command = 'P' then Put_to_file    else
  457.       if command = 'G' then Get_from_file  else
  458.       if command = 'S' then Sort_form      else
  459.       if command = 'B' then Bad_grades
  460.       else Unknown_command(command);
  461.       command := prompt_for_char("Your next command > ");
  462.     end;
  463.   User_message("Bye");
  464.  
  465. end
  466.